#pragma once

#include "Log.hpp"
#include <jsoncpp/json/json.h>

const string inner_sep = " ";
const string protocol_sep = "\n";

//传入报文正文部分，添加报头，以及报文与报文之间的分隔符
//"left op right" => "len"\n"left op right"\n
string Encode(string& content)
{
    string s = to_string(content.size());
    s += protocol_sep;
    s += content;
    s += protocol_sep;

    return s;
}

//"len"\n"left op right"\nXXXXX... => "left op right"
bool Decode(string& in,string* content)
{
    size_t pos = in.find("\n");
    if(pos == string::npos)
    {
        return false;
    }

    string len_s = in.substr(0,pos);
    int len = stoi(len_s);

    //待解码的报文不完整
    int total_len = len_s.size() + len + 2;
    if(in.size() < total_len)
    {
        return false;
    }

    *content = in.substr(pos+1,len);

    //移除已经被处理的报文
    in.erase(0,total_len);

    return true;
}

// 网络计算器
class Request
{
public:
    Request(int left, int right, char op)
        : _left(left), _right(right), _op(op)
    {
        ;
    }

    Request()
    {
        ;
    }

    // left op right => "left op right"
    bool Serialize(string *out)
    {
#ifdef MYSELF
        string s;
        s += to_string(_left);
        s += inner_sep;
        s += _op;
        s += inner_sep;
        s += to_string(_right);

        *out = s;

        return true;
#else
    Json::Value root;
    root["left"] = _left;
    root["right"] = _right;
    root["op"] = _op;

    Json::FastWriter w;
    *out = w.write(root);
    return true;
#endif
    }

    //"left op right" => left op right
    bool Deserialize(const string &in)
    {
#ifdef MYSELF
        size_t leftPos = in.find(" ");
        if (leftPos == string::npos)
        {
            return false;
        }

        string left = in.substr(0, leftPos);

        size_t rightPos = in.rfind(" ");
        if (rightPos == string::npos)
        {
            return false;
        }

        string right = in.substr(rightPos + 1);

        // 报文里的核心数据格式错误
        if (leftPos + 2 != rightPos)
        {
            return false;
        }

        _op = in[leftPos + 1];
        _left = stoi(left);
        _right = stoi(right);

        return true;

#else
    Json::Value root;
    Json::Reader r;
    r.parse(in,root);
    _left = root["left"].asInt();
    _right = root["right"].asInt();
    _op = root["op"].asInt();
    return true;
#endif
    }

public:
    int _left;
    int _right;
    char _op;
};

class Response
{
public:
    Response(int result, int code)
        : _result(result), _code(code)
    {
        ;
    }

    Response()
    {
        ;
    }

    // result code => "result code"
    bool Serialize(string *out)
    {
#ifdef MYSELF
        string s = to_string(_result) + inner_sep + to_string(_code);

        *out = s;

        return true;
#else
    Json::Value root;
    root["result"] = _result;
    root["code"] = _code;
    Json::FastWriter w;
    *out = w.write(root);
    return true;
#endif
    }

    //"result code" => result code
    bool Deserialize(const string &in)
    {
#ifdef MYSELF
        size_t pos = in.find(" ");
        if (pos == string::npos)
        {
            return false;
        }

        string result = in.substr(0,pos);
        string code = in.substr(pos+1);

        size_t rpos = in.rfind(" ");
        if (rpos == string::npos)
        {
            return false;
        }

        // 报文里的核心数据格式错误
        if(rpos != pos)
        {
            return false;
        }

        _result = stoi(result);
        _code = stoi(code);

        return true;
        
#else
    Json::Value root;
    Json::Reader r;
    r.parse(in,root);
    _result = root["result"].asInt();
    _code = root["code"].asInt();
    return true;
#endif
    }

public:
    int _result;
    int _code; // 错误码，0表示没有出错，其他表示出错
};